class_name Player
extends Character



@onready var sprite: Sprite2D = $Sprite2D
@onready var weapon_slot: Node2D = $WeaponSlot
@onready var weapon_slot1: Node2D = $WeaponSlot/Slot1
@onready var weapon_slot2: Node2D = $WeaponSlot/Slot2
@onready var animation_player: AnimationPlayer = $AnimationPlayer
@onready var state_machine: StateMachine = $StateMachine
@onready var damage_receiver: DamageReceiver = $DamageReceiver
@onready var motion_particles: GPUParticles2D = $MotionParticles
@onready var camera_remote_transform: RemoteTransform2D = $CameraRemoteTransform
# @onready var collision_shape: CollisionShape2D = $CollisionShape2D


@export var can_control: bool = true:
    set(value):
        can_control = value
        if state_machine:
            state_machine.active = can_control


var is_invincibility: bool = false:
    set(value):
        is_invincibility = value
        damage_receiver.disabled = is_invincibility


var is_attacking: bool = false
var current_weapon: Weapon:
    set(value):
        var old := current_weapon
        current_weapon = value

        if old != current_weapon:
            weapon_changed.emit(old, current_weapon)


signal weapon_changed(old: Weapon, new: Weapon);


func _ready() -> void:
    # 冲刺次数恢复, (暂时实现)
    data.dash_count.value_changed.connect(
        func(ov: float, nv: float) -> void:
            if nv < ov:
                await get_tree().create_timer(data.dash_restore_time).timeout
                data.dash_count.add_modifier(1)
    )

    # 依据攻击速度修改装备武器的射击速度
    data.attack_speed.value_changed.connect(
        func(_ov: float, nv: float) -> void:
            var wp1 := get_weapon(0)
            var wp2 := get_weapon(1)

            if wp1: wp1.shoot_speed = nv
            if wp2: wp2.shoot_speed = nv
    )

    # handle_damage_signals.receive_damage_applied.connect(
    #     func(_info: DamageInfo) -> void:
    #         animation_player.play("had_damage")
    # )


    # can_control = true

    # weapon_slot1.get_child(0).equip(self)
    # weapon_slot2.get_child(0).equip(self)


func _process(_delta: float) -> void:
    if not can_control: return

    _face_and_weapon_follow_mouse()
    _set_motion_particles_visible()
    _attack()
    

func _set_weapon_follow_mouse(slot: Node2D, direction: Vector2) -> void:
    if slot.get_child_count() == 0: return
    var wp := slot.get_child(0) as Weapon
    # if not wp: return

    if direction.x >= 0:
        slot.scale.x = abs(slot.scale.x)
        if wp.rotate_follow_mouse: slot.rotation = direction.angle()
    else:
        slot.scale.x = -abs(slot.scale.x)
        if wp.rotate_follow_mouse: slot.rotation = direction.angle() - PI



func _face_and_weapon_follow_mouse() -> void:
    var offset := get_global_mouse_position() - global_position
    sprite.flip_h = false if offset.x >= 0 else true
    _set_weapon_follow_mouse(weapon_slot1, offset)
    _set_weapon_follow_mouse(weapon_slot2, offset)



func _set_motion_particles_visible() -> void:
    motion_particles.emitting = not velocity.is_zero_approx()


func _attack() -> void:
    is_attacking = false
    if Input.is_action_pressed("weapon1_attack") and weapon_slot1.get_child_count() != 0:
        weapon_slot2.hide()
        weapon_slot1.show()
        current_weapon = weapon_slot1.get_child(0)
        current_weapon.attack()
        is_attacking = true
    elif Input.is_action_pressed("weapon2_attack") and weapon_slot2.get_child_count() != 0:
        weapon_slot1.hide()
        weapon_slot2.show()
        current_weapon = weapon_slot2.get_child(0)
        current_weapon.attack()
        is_attacking = true
        

## override
func be_static(val: bool) -> void:
    animation_player.pause()
    can_control = not val


func can_dash() -> bool:
    return data.dash_count.value > 0


func get_weapon(idx: int) -> Weapon:
    return weapon_slot.get_child(idx).get_child(0)


func equip_weapon(slot_idx: int, wp: Weapon) -> void:
    weapon_slot.get_child(slot_idx).add_child(wp)
    wp.equip(self)


func bind_camera(camera: Camera2D) -> void:
    camera_remote_transform.remote_path = camera_remote_transform.get_path_to(camera)
